{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "04791372",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "共享密钥匹配。\n",
      "Alice私钥: 50952439223511318976630400478003965041144106727748610293304410902869239330811\n",
      "Alice公钥: (92746483208777695508560700680934882735705979728792590447430346540582361228454, 66217780290965791475707340859868708207645667755006713282791815034767971542429)\n",
      "Bob私钥: 18609068850573238700875229574495128687153296052485764665493071177185381751296\n",
      "Bob公钥: (11308008921663323384468674114198373129190461350790303944393809094306860179766, 84841480064942187218571731920622600402300737287267361824815657342063147268329)\n",
      "共享密钥: (33699628410282919995256606613986952104572466712617114968414429495337503428685, 36679595111031004241885812996681622576755521884837793963392824957856551715505)\n"
     ]
    }
   ],
   "source": [
    "# 椭圆曲线Diffie-Hellman算法 ECDH\n",
    "\n",
    "from py_ecc.secp256k1 import secp256k1\n",
    "import os\n",
    "\n",
    "def generate_keys():\n",
    "    private_key = int.from_bytes(os.urandom(32), 'big') % secp256k1.N\n",
    "    public_key = secp256k1.multiply(secp256k1.G, private_key)\n",
    "    return private_key, public_key\n",
    "\n",
    "# Alice和Bob生成各自的密钥对\n",
    "alice_private, alice_public = generate_keys()\n",
    "bob_private, bob_public = generate_keys()\n",
    "\n",
    "# 计算共享密钥\n",
    "shared_secret_alice = secp256k1.multiply(bob_public, alice_private)\n",
    "shared_secret_bob = secp256k1.multiply(alice_public, bob_private)\n",
    "\n",
    "assert shared_secret_alice == shared_secret_bob, \"共享密钥不匹配！\"\n",
    "print(\"共享密钥匹配。\")\n",
    "\n",
    "print(f\"Alice私钥: {alice_private}\")\n",
    "print(f\"Alice公钥: {alice_public}\")\n",
    "\n",
    "print(f\"Bob私钥: {bob_private}\")\n",
    "print(f\"Bob公钥: {bob_public}\")\n",
    "\n",
    "print(f\"共享密钥: {shared_secret_alice}\")\n",
    "\n",
    "# 共享密钥匹配。\n",
    "# Alice私钥: 44226773042722162955098193291492534006186517732096623157459837212766793078584\n",
    "# Alice公钥: (113906392817926084413632896524344771269472367375880032535005632965062391078788, 49665636540644454541653315656482000530366349019751676160955522917215379042285)\n",
    "# Bob私钥: 51860882402071446551116109914681284224864199234652843480335793819475548437366\n",
    "# Bob公钥: (52340819409831460217804635786419806447405367609650964443132838196582132856471, 56429557458241459690871510882159471830396052430769816127197158365607969924309)\n",
    "# 共享密钥: (39817116182924354378808003014233470575110979407770339130416639641795260327693, 42970388080766198583159133018251494914868250846130428856587988974064644921855)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "a3a9123c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始消息明文: (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)\n",
      "加密后的消息: ((87298472810248234319752437423707505477343664832890363292431829216099637291919, 39528614830056678009484946030376271359657183017625571564228160252781333158439), (67113196324182438503834247973075313606138491143388276462715763950508942145812, 59499979624168470896804403233074133393632477568643779021536973756576878140912))\n",
      "解密后的消息: (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)\n",
      "消息成功解密！\n"
     ]
    }
   ],
   "source": [
    "# EC ElGamal\n",
    "\n",
    "from py_ecc.secp256k1 import secp256k1\n",
    "from random import randint\n",
    "\n",
    "def elgamal_encrypt(G, Y, M):\n",
    "    k = randint(1, secp256k1.N - 1)\n",
    "    C1 = secp256k1.multiply(G, k)\n",
    "    C2 = secp256k1.add(M, secp256k1.multiply(Y, k))\n",
    "    return (C1, C2)\n",
    "\n",
    "def elgamal_decrypt(C1, C2, x):\n",
    "    # 使用私钥x计算xC1\n",
    "    xC1 = secp256k1.multiply(C1, x)\n",
    "    # 计算M = C2 - xC1\n",
    "    M = secp256k1.add(C2, (xC1[0], -xC1[1]))\n",
    "    return M\n",
    "\n",
    "# 示例参数\n",
    "p = secp256k1.N\n",
    "G = secp256k1.G\n",
    "\n",
    "# 生成密钥对\n",
    "x, Y = generate_keys()\n",
    "\n",
    "# 假设消息M是曲线上的一个点，这里简单选择G作为示例\n",
    "M = G\n",
    "print(\"原始消息明文:\", M)\n",
    "\n",
    "# 加密\n",
    "C1, C2 = elgamal_encrypt(G, Y, M)\n",
    "print(\"加密后的消息:\", (C1, C2))\n",
    "\n",
    "# 解密\n",
    "M_decrypted = elgamal_decrypt(C1, C2, x)\n",
    "print(\"解密后的消息:\", M_decrypted)\n",
    "\n",
    "# 验证\n",
    "assert M == M_decrypted, \"解密失败！\"\n",
    "print(\"消息成功解密！\")\n",
    "\n",
    "# 示例输出\n",
    "# 原始消息明文: (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)\n",
    "# 加密后的消息: ((87298472810248234319752437423707505477343664832890363292431829216099637291919, 39528614830056678009484946030376271359657183017625571564228160252781333158439), (67113196324182438503834247973075313606138491143388276462715763950508942145812, 59499979624168470896804403233074133393632477568643779021536973756576878140912))\n",
    "# 解密后的消息: (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)\n",
    "# 消息成功解密！\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c841e756",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始消息明文: b'Hello, ECDSA with secp256k1!'\n",
      "签名: (6499963749864329771556157957492284712510167478804544523000435554134517260884, 408133531747173327519932028935044420196907448924380145454734214962901704560)\n",
      "签名验证结果: True\n"
     ]
    }
   ],
   "source": [
    "# ECDSA\n",
    "\n",
    "from py_ecc.secp256k1 import secp256k1\n",
    "import os\n",
    "import hashlib\n",
    "\n",
    "def generate_keys():\n",
    "    # 生成私钥\n",
    "    private_key = os.urandom(32)\n",
    "    private_key_int = int.from_bytes(private_key, 'big') % secp256k1.N\n",
    "    # 生成公钥\n",
    "    public_key = secp256k1.multiply(secp256k1.G, private_key_int)\n",
    "    return private_key_int, public_key\n",
    "\n",
    "def ecdsa_sign(message, private_key):\n",
    "    # 对消息进行哈希处理\n",
    "    message_hash = hashlib.sha256(message).digest()\n",
    "    message_hash_int = int.from_bytes(message_hash, 'big')\n",
    "    \n",
    "    k = int.from_bytes(os.urandom(32), 'big') % secp256k1.N\n",
    "    R = secp256k1.multiply(secp256k1.G, k)\n",
    "    r = R[0] % secp256k1.N\n",
    "    s = ((message_hash_int + r * private_key) * secp256k1.inv(k, secp256k1.N)) % secp256k1.N\n",
    "    \n",
    "    return (r, s)\n",
    "\n",
    "def ecdsa_verify(message, signature, public_key):\n",
    "    r, s = signature\n",
    "    message_hash = hashlib.sha256(message).digest()\n",
    "    message_hash_int = int.from_bytes(message_hash, 'big')\n",
    "    \n",
    "    w = secp256k1.inv(s, secp256k1.N)\n",
    "    u1 = (message_hash_int * w) % secp256k1.N\n",
    "    u2 = (r * w) % secp256k1.N\n",
    "    \n",
    "    P = secp256k1.add(secp256k1.multiply(secp256k1.G, u1), secp256k1.multiply(public_key, u2))\n",
    "    \n",
    "    return r == P[0] % secp256k1.N\n",
    "\n",
    "# 示例\n",
    "x, Y = generate_keys()\n",
    "M = b\"Hello, ECDSA with secp256k1!\"\n",
    "print(\"原始消息明文:\", M)\n",
    "\n",
    "signature = ecdsa_sign(M, x)\n",
    "print(\"签名:\", signature)\n",
    "\n",
    "valid = ecdsa_verify(M, signature, Y)\n",
    "print(\"签名验证结果:\", valid)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8f12eafb",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
